package com.jvm;

/**
 * @author: 李德才
 * @description:
 * @create: 2021-06-19 18:46
 **/
public class JVM_14_CacheLine {

    /**
     * https://blog.csdn.net/qq_36623327/article/details/107722173?spm=1001.2014.3001.5501
     * cpu加载数据 arr 数组时会将相近的数据同时加载到缓存中，一般为64个字节，这个存储单元一般称为缓存行
     * 因为线程 t1 t2 操作同一个缓存行的中数据，为了保证数据一致性，当arr[1] 被修改，就需要通知 t2 线程
     * 频繁的通信造成资源的浪费
     * 注意：这里面的 arr[0] 和 arr[1] 不一定在同一个缓存行中，代码只是为了表述现象
     * <p>
     * <p>
     * 但是如果将两个对象分别存放在不同的缓存行中
     * 则一方被修改就不用通知其他线程，因此效率增加
     **/

    public static volatile long[] arr = new long[2];

    public static void cacheLine1() throws InterruptedException {
        Thread t1 = new Thread(() -> {
            for (long i = 0; i < 10000_0000L; i++) {
                arr[0] = i;
            }
        });
        Thread t2 = new Thread(() -> {
            for (long i = 0; i < 10000_0000L; i++) {
                arr[1] = i;
            }
        });
        final long start = System.nanoTime();
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println((System.nanoTime() - start) / 100_0000);
    }

    /**
     * ------------------------------------我是分割线--------------------------------------
     **/

    public static volatile long[] arr2 = new long[16];

    public static void cacheLine2() throws InterruptedException {
        Thread t1 = new Thread(() -> {
            for (long i = 0; i < 10000_0000L; i++) {
                arr2[0] = i;
            }
        });

        Thread t2 = new Thread(() -> {
            for (long i = 0; i < 10000_0000L; i++) {
                arr2[8] = i;
            }
        });

        final long start = System.nanoTime();
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println((System.nanoTime() - start) / 100_0000);
    }


    public static void main(String[] args) throws InterruptedException {
        cacheLine2();
        cacheLine1();
    }

}